package probe.sound.spectrum;

import static java.lang.Math.PI;
import static java.lang.Math.cos;
import static java.lang.Math.sin;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import probe.sound.core.Producer;
import probe.sound.core.Syn;
import probe.sound.core.SynWave;
import probe.sound.core.Value;

public class PlayOne implements Producer {
  public static void main(String[] args) {
    new PlayOne().run();
  }
  
  public static void main1(String[] args) throws Exception {
    PlayOne x = new PlayOne();
    
    x.loadGammaList();
    
    for (Gamma gamma : x.gammaList) {
      System.out.println(gamma);
    }
  }
  
  private void run() {
    //Syn play = new SynPlay();
    Syn play = new SynWave(System.getProperty("user.home") + "/tmp/wow.wav");
    
    play.setProducer(this);
    play.setTimeDelay(2);
    
    play.run();
    
    System.out.println("OK");
  }
  
  private static final double PI2 = PI * 2;
  
  private static class Gamma {
    
    double Hz;
    double A;
    
    @Override
    public String toString() {
      return "Gamma [Hz=" + Hz + ", A=" + A + "]";
    }
  }
  
  private List<Gamma> gammaList;
  
  @Override
  public void produce(Value value, double t) throws Exception {
    if (gammaList == null) loadGammaList();
    double v = 0;
    int i = 0;
    for (Gamma gamma : gammaList) {
      if (i++ % 2 == 0) {
        v += gamma.A * cos(gamma.Hz * PI2 * t);
      } else {
        v -= gamma.A * sin(gamma.Hz * PI2 * t);
      }
    }
    
    value.right = value.left = v;
  }
  
  private void loadGammaList() throws Exception {
    InputStream in = getClass().getResourceAsStream("spec.01.txt");
    BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
    String line = null;
    while ((line = br.readLine()) != null) {
      String[] split = line.trim().split("\\s+");
      
      if (split.length == 2) {
        Gamma g = new Gamma();
        g.Hz = Double.parseDouble(split[0]);
        double d2 = Double.parseDouble(split[1]);
        g.A = Math.exp(d2 / 10 * Math.log(10));
        
        if (gammaList == null) gammaList = new ArrayList<PlayOne.Gamma>();
        gammaList.add(g);
      }
    }
    br.close();
  }
}
